home *** CD-ROM | disk | FTP | other *** search
- /*-------------------------------------------------------------------
-
- AOCE Post Office Protocol (POP) / Simple Mail Transfer Protocol (SMTP)
- Mail Service Access Module
-
- written by Steve Falkenburg-- MacDTS
- ©1991-1993 Apple Computer, Inc.
-
- --------------
- change history
- --------------
-
- SJF 02/19/93 update for beta build b1
- SJF 10/29/92 update to a11 a11
- SJF 06/08/92 update to a8 a8
- SJF 02/15/92 first working version a4.5
- SJF 10/16/91 initial coding a3
-
- ---------------------------------------------------------------------*/
-
- #ifndef __TYPES__
- #include <Types.h>
- #endif
-
- #ifndef __OCE__
- #include <OCE.h>
- #endif
-
- #ifndef __OCEMAIL__
- #include <OCEMail.h>
- #endif
-
- #include <string.h>
-
- #include "const.h"
- #include "gwerrors.h"
- #include "mytypes.h"
- #include "globals.h"
- #include "utils.h"
- #include "parser.h"
- #include "pop.constants.h"
- #include "pop.protocol.h"
- #include "convertaddress.h"
- #include "spoolsystem.h"
- #include "spooltoaoce.h"
- #include "spoolfromexternal.h"
- #include "network.h"
-
- // DoSlotPut
- //
- // called to get messages for this slot from the external network and put them into
- // the system via the toolbox
- //
- OSErr DoSlotPut(SlotSpec *slot)
- {
- OSErr err;
- unsigned long popServerAddress,popConnID;
- short numMessages,numMsgIDs,messageIDIndex;
- long mboxLength;
- TMsgIDList messageIDs; // allocated by routine called from here, de-allocated by us
- TMsgID curMessageID;
- Ptr headerData; // allocated by routine called from here, de-allocated by us
- FSSpec spoolSpec;
-
- TraceExecution("\pDoSlotPut");
-
- /* first, we need to grab the letters from POP and spool them */
-
- err = InitRemoteNetStuff();
- if (err!=noErr)
- return err;
-
- err = ConvertStringToAddr(slot->specInfo.popServer,&popServerAddress);
- if (err!=noErr) {
- return kInvalidPopServer;
- }
-
- err = POP_InitiateConnection(popServerAddress,kPopPort,slot->dirIdentity.userName,slot->dirIdentity.password,&popConnID);
- if (err!=noErr) {
- return err;
- }
-
- err = POP_GetDropStats(popConnID,&numMessages,&mboxLength);
- if (err!=noErr) {
- POP_CloseConnection(popConnID);
- return err;
- }
-
- err = POP_GetMessageIDs(popConnID,&messageIDs,&numMsgIDs); // messageIDs allocated by call
- if (err!=noErr) {
- POP_CloseConnection(popConnID);
- return err;
- }
-
- for (messageIDIndex=0; messageIDIndex<numMsgIDs; messageIDIndex++) {
-
- err = CreateSpoolFile(&spoolSpec); // make our spool file
- if (err!=noErr)
- return err;
-
- curMessageID = messageIDs[messageIDIndex];
- err = POP_GetMessage(popConnID,curMessageID,&headerData,&spoolSpec);
-
- if (err==noErr) {
-
- err = SpoolFromPOP(&spoolSpec,headerData,slot); // spool message into aoce form
- if (err==noErr)
- err = SpoolIntoAOCE(&spoolSpec,slot); // send spooled msg to aoce
-
- if (err!=noErr) {
- POP_CloseConnection(popConnID);
- return err;
- }
- DisposPtrChk(headerData);
- if (MemError()!=noErr) {
- POP_CloseConnection(popConnID);
- return err;
- }
-
- err = POP_DeleteMessage(popConnID,curMessageID);
-
- }
- if (err!=noErr) {
- POP_CloseConnection(popConnID);
- return err;
- }
-
- RemoveSpoolFile(&spoolSpec);
-
- }
-
- if (numMsgIDs!=0) {
- DisposPtrChk(messageIDs);
- if (MemError()!=noErr) {
- POP_CloseConnection(popConnID);
- return err;
- }
- }
-
- err = POP_CloseConnection(popConnID);
- return err;
- }
-
-
- OSErr SpoolFromPOP(FSSpec *spoolSpec,Ptr header,SlotSpec *slot)
- {
- long headerLength;
- OSErr err;
- char *headerData;
- RString rStr;
-
- headerData = (char *)NewPtrChk(kMaxRecipSize);
- if (MemError()!=noErr)
- return MemError();
-
- headerLength = strlen(header);
-
- // spool from
-
- err = ExtractHeaderLine("From:",headerData,header);
- if (err==noErr) {
- err = SpoolAddresses(headerData,spoolSpec,kFromType,kAddrCreator,slot);
- if (err!=noErr) {
- DisposPtrChk((Ptr)headerData);
- return err;
- }
- }
- else {
- // no from address, so put ourselves in the from...
- strcpy(headerData,slot->dirIdentity.userName);
- strcat(headerData,"@");
- strcat(headerData,slot->specInfo.popServer);
- err = SpoolAddresses(headerData,spoolSpec,kFromType,kAddrCreator,slot);
- if (err!=noErr) {
- DisposPtrChk((Ptr)headerData);
- return err;
- }
- }
-
- // spool to
-
- err = ExtractHeaderLine("To:",headerData,header);
- if (err==noErr) {
- err = SpoolAddresses(headerData,spoolSpec,kToType,kAddrCreator,slot);
- if (err!=noErr) {
- DisposPtrChk((Ptr)headerData);
- return err;
- }
- }
- else {
- // no to address, so put ourselves in as to so things will work (somewhat)
- strcpy(headerData,slot->dirIdentity.userName);
- strcat(headerData,"@");
- strcat(headerData,slot->specInfo.popServer);
- err = SpoolAddresses(headerData,spoolSpec,kToType,kAddrCreator,slot);
- if (err!=noErr) {
- DisposPtrChk((Ptr)headerData);
- return err;
- }
- }
-
- // spool CC (optional)
-
- err = ExtractHeaderLine("Cc:",headerData,header);
- if (err==noErr) {
- err = SpoolAddresses(headerData,spoolSpec,kCCType,kAddrCreator,slot);
- if (err!=noErr) {
- DisposPtrChk((Ptr)headerData);
- return err;
- }
- }
-
- // spool BCC (optional)
-
- err = ExtractHeaderLine("Bcc:",headerData,header);
- if (err==noErr) {
- err = SpoolAddresses(headerData,spoolSpec,kBCCType,kAddrCreator,slot);
- if (err!=noErr) {
- DisposPtrChk((Ptr)headerData);
- return err;
- }
- }
-
- // spool subject
-
- err = ExtractHeaderLine("Subject:",headerData,header);
- if (err==noErr) {
- OCECToRString(headerData,smRoman,&rStr,kRStringMaxBytes);
- err = SpoolToFile(spoolSpec,kSubjectType,kAttribCreator,0,(Ptr)&rStr,(unsigned long)rStr.dataLength+4);
- if (err!=noErr) {
- DisposPtrChk((Ptr)headerData);
- return err;
- }
- }
-
- // spool message body
-
- err = SpoolMessageBody(spoolSpec);
- if (err!=noErr) {
- DisposPtrChk((Ptr)headerData);
- return err;
- }
-
- DisposPtrChk((Ptr)headerData);
- return err;
- }
-
-
- OSErr ExtractHeaderLine(char *header,char *contents,char *text)
- {
- char *lineEnd,*curLine,*tmpWord;
-
- lineEnd = text;
- while (*lineEnd) {
- GetLine(&curLine,&lineEnd);
- if (strstr(curLine,header)==curLine) {
- GetWord(&tmpWord,&curLine);
- CopyAndUnfoldLine(contents,curLine);
- return noErr;
- }
- }
-
- return kUnexpectedDataCondition;
- }
-
-
- OSErr SpoolAddresses(char *headerLine,FSSpec *spoolSpec,OSType spoolType,OSType spoolCreator,SlotSpec *slot)
- {
- OSErr err;
- short index;
- char *tAddress,*startAddr,*endAddr,*realName;
- char singleAddr[256];
- short addrLen;
-
- // rli variables
-
- RLI rli;
- PackedRLI pRLI;
-
- // rid types
-
- CreationID cid;
- RString rName,rType;
- LocalRecordID localRID;
- RecordID RID;
-
- DSSpec theRecipient;
- char pRecipient[kMaxRecipSize];
- unsigned long pRecipLength;
- RString xtnValueRStr;
-
- err = noErr;
- index = 0;
-
- while (*headerLine && err==noErr) {
- GetField(&tAddress,&headerLine,',',&addrLen);
- strncpy(singleAddr,tAddress,addrLen);
- singleAddr[addrLen] = '\0';
- realName = startAddr = endAddr = nil;
-
- // search for "xxxxx <addr>" style address
-
- if (startAddr=strstr(singleAddr,"<")) { // got one
- *startAddr = '\0';
- startAddr++;
- endAddr = strstr(startAddr,">");
- *endAddr = '\0';
- realName = singleAddr;
- }
-
- // if not, assume "addr (xxxxxxx)" style address
-
- else {
- startAddr = singleAddr;
- endAddr=strstr(singleAddr," ");
- if (endAddr) {
- *endAddr = '\0';
- realName = strstr(singleAddr,"(");
- if (realName) {
- endAddr = strstr(realName,")");
- if (endAddr)
- *endAddr = '\0';
- else
- realName = nil;
- }
- }
- }
-
- if (!startAddr) // at this point, realName points to the user's real name
- return kUnexpectedDataCondition; // and startAddr points to their e-mail address
-
- if (!realName || *realName==0)
- realName = startAddr;
-
- // make our RLI (and pack it)
-
- OCENewRLI(&rli,(DirectoryNamePtr)&slot->directoryName,&slot->discriminator,kNULLDNodeNumber,nil);
- if (!OCEValidRLI(&rli))
- return kUnexpectedAOCECondition;
- err = OCEPackRLI(&rli,&pRLI,kRLIMaxBytes);
- if (err!=noErr)
- return err;
- if (!OCEValidPackedRLI(&pRLI))
- return kUnexpectedAOCECondition;
-
- // set up name, type rstrings and creation ID for local RID
-
- OCESetCreationIDtoNull(&cid);
- OCECToRString(kUserRecTypeBody,smRoman,&rType,kRStringMaxBytes);
- OCECToRString(realName,smRoman,&rName,kRStringMaxBytes);
-
- // make the local RID and the RID
-
- OCENewLocalRecordID (&rName,&rType,&cid,&localRID);
- OCENewRecordID(&pRLI,&localRID,&RID);
-
- theRecipient.entitySpecifier = &RID;
- theRecipient.extensionType = kPopAddrType;
- OCECToRString(startAddr,smRoman,&xtnValueRStr,kRStringMaxChars);
- theRecipient.extensionSize = xtnValueRStr.dataLength+4;
- theRecipient.extensionValue = (Ptr)&xtnValueRStr;
-
- pRecipLength = OCEPackedDSSpecSize(&theRecipient);
- OCEPackDSSpec(&theRecipient,(PackedDSSpec *)&pRecipient,pRecipLength);
-
- err = SpoolToFile(spoolSpec,spoolType,spoolCreator,index++,(Ptr)&pRecipient,pRecipLength);
- }
-
- return err;
- }
-
-
- /* this call should read the raw unprocessed content out of the spool and write aoce formatted
- content into the spool. here's where we should insert clever code to extract picts, sound,
- styled text, movies, and enclosures but for right now, we only support one huge text block */
-
- OSErr SpoolMessageBody(FSSpec *spoolSpec)
- {
- OSErr err;
- Ptr bodyBuffer;
- unsigned long dataLength,startOffset;
-
- bodyBuffer = NewPtrChk(kMaxBufferSize);
- if (MemError()!=noErr)
- return MemError();
-
- startOffset = 0;
- do {
- dataLength = kMaxBufferSize;
- err = GetFromSpool(spoolSpec,kRawContentType,kRawContentCreator,0,bodyBuffer,
- &dataLength,startOffset);
- if ((err==noErr)||(err==kMoreData)) {
- if (startOffset==0)
- SpoolToFile(spoolSpec,kTextContent,kContentCreator,0,bodyBuffer,dataLength);
- else
- AppendToSpool(spoolSpec,kTextContent,kContentCreator,0,bodyBuffer,dataLength);
- startOffset += dataLength;
- }
- } while (err==kMoreData);
-
- if (err==kMoreData)
- err = noErr;
-
- DisposPtrChk(bodyBuffer);
-
- return err;
- }